package com.feng.study.demo.designpattern;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 单例模式
 * DCL
 * 枚举
 * 反射打破单例
 */
public class SingleDemo {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        UserSingleHungry instance = UserSingleHungry.getInstance();
        UserSingleLazy instance1 = UserSingleLazy.getInstance();

        UserSingleLazyDCL userSingleLazyDCL01 = UserSingleLazyDCL.getInstance();

        // 反射打破单例
//        UserSingleLazyDCL userSingleLazyDCL = UserSingleLazyDCL.class.newInstance();
        Constructor<UserSingleLazyDCL> declaredConstructor = UserSingleLazyDCL.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        UserSingleLazyDCL userSingleLazyDCL02 = declaredConstructor.newInstance();
        System.out.println(userSingleLazyDCL01);
        System.out.println(userSingleLazyDCL02);
    }
}

class UserSingleHungry {

    private static UserSingleHungry userSingleHungry = new UserSingleHungry();

    private UserSingleHungry() {
        System.out.println("UserSingleHungry调用无参构造创建了对象：");
    }

    public static UserSingleHungry getInstance() {
        return userSingleHungry;
    }
}

class UserSingleLazy {

    private static UserSingleLazy userSingleLazy;

    private UserSingleLazy() {
        System.out.println("UserSingleLazy调用无参构造创建了对象：");
    }

    public static UserSingleLazy getInstance() {
        if (userSingleLazy == null) {
            userSingleLazy = new UserSingleLazy();
        }
        return userSingleLazy;
    }
}


class UserSingleLazyDCL {

    private volatile static UserSingleLazyDCL userSingleLazyDCL;

    private UserSingleLazyDCL() {
        System.out.println("UserSingleLazyDCL调用无参构造创建了对象：");
    }

    public static UserSingleLazyDCL getInstance() {
        // 第一次检测
        if (userSingleLazyDCL == null) {
            synchronized(UserSingleLazyDCL.class){
                // 第二次检测
                if (userSingleLazyDCL == null) {
                    userSingleLazyDCL = new UserSingleLazyDCL();
                }
            }
        }

        return userSingleLazyDCL;
    }
}